/**
 * Copyright (c) 快宝网络 kuaidihelp.com Co., Ltd. All Rights Reserved 禁止外泄以及用于其它的商业用途
 */

import React, { useEffect, useCallback, useState, useRef } from 'react';
import { connect } from 'dva';
import { Row, Col, message } from 'antd';
import MapChart from '@/components/Charts/MapChart';
import { fixNanHai, isPointInPolygon, transformAreaName } from './_utils';
import CommonBorder from './Wrappers/CommonBorder';
import ChartBreadcrumb from './ChartBreadcrumb';
import NoDate from './Wrappers/NoDate';
import styles from './Map.less';
import DetailModal from './DetailModal';

const levelMap = {
  province: 1,
  city: 2,
  district: 3,
  town: 4,
};

const Map = ({ dispatch, loading, currentUser, isParentFull, screenToken }) => {
  const { branchLevel: userLevel } = currentUser;
  const [mapLoading, setMapLoading] = useState(false);
  const [mapData, setMapData] = useState(null);
  const level = useRef(userLevel);
  const dataValue = useRef([]);
  const widthRef = useRef({});
  const [width, setWidth] = useState(0);
  const [visible, setVisible] = useState(false);
  const [cmId, setCmId] = useState('');

  const currentUserLevel = useRef([]);
  const timer = useRef(null);
  const parentMapGeoData = useRef([]);

  // 更新地区层级信息
  const updateAreaInfo = useCallback(
    ({ branchId, name, branchLevel, adcode }) => {
      level.current = branchLevel;
      const arr = [...currentUserLevel.current];
      const lastItemLevel = arr[arr.length - 1]?.branchLevel;
      const currentClickIndex = arr.findIndex(val => val.branchLevel == branchLevel);

      if (lastItemLevel < branchLevel) {
        arr.push({
          adcode,
          branchId,
          name,
          branchLevel,
        });
      }
      if (lastItemLevel > branchLevel) {
        arr.splice(currentClickIndex + 1, arr.length - 1);
      }
      currentUserLevel.current = arr;
      // 全局层级更新
      dispatch({
        type: 'chartData/updateAreaInfo',
        payload: {
          currentUserLevel: arr,
          branchId,
          currentName: name,
          currentLevel: branchLevel,
        },
      });
    },
    [dispatch, currentUserLevel, userLevel],
  );

  // 获取地图数据
  const updateMapData = useCallback(
    // eslint-disable-next-line no-shadow
    (branchId, adcode, level, parentAdCode) => {
      setMapLoading(true);
      dispatch({
        type: 'chartData/getAreaYzData',
        payload: {
          code: branchId,
          level,
          token: screenToken,
        },
      }).then((res = []) => {
        dataValue.current = res;
        dispatch({
          type: 'chartData/getMapData',
          payload: {
            adcode,
            token: screenToken,
            level,
            parentAdCode,
          },
        }).then(data => {
          // 村一级过滤不在地图内的驿站点
          if (level == 4) {
            let filterData = [...res];
            filterData = filterData.filter(val => {
              const currentPoint = {
                lng: val.longitude,
                lat: val.latitude,
              };
              return isPointInPolygon(currentPoint, parentMapGeoData.current);
            });
            dataValue.current = filterData;
          }
          setMapData({
            ...data,
            features: fixNanHai(data.features, adcode),
          });
        });
      });
      setTimeout(() => {
        setMapLoading(false);
      }, 2500);
    },
    [dispatch, screenToken],
  );

  const onMapClick = useCallback(
    e => {
      const { data = {} } = e;
      const { _origin = {} } = data;
      const { properties = {}, num, geometry = {}, cm_id } = _origin;
      const { coordinates = [] } = geometry;
      // eslint-disable-next-line no-shadow
      const { adcode, name, level, parent } = properties;
      if (cm_id) {
        setVisible(true);
        setCmId(cm_id);
        return;
      }

      if (!adcode || !levelMap[level]) return;
      if (adcode && (num == 0 || !num)) {
        if (levelMap[level] < 3) {
          message.error('此地区暂无数据！');
          return;
        }
      }

      // 金华，丽水，衢州市
      if (levelMap[level] == 3 && ![330700, 331100, 330800].includes(parent.adcode)) {
        return;
      }

      // 丽水，衢州市
      const city = [331100, 330800];
      // 遂昌县，衢江区
      const district = [331123, 330803];
      // 访问指定的区县下一级
      if (city.includes(parent.adcode) && !district.includes(adcode)) {
        return;
      }

      // 储存父一级地图边界数据
      if (levelMap[level] == 4) {
        parentMapGeoData.current = coordinates[0].map(val => ({
          lng: val[0],
          lat: val[1],
        }));
      }

      let branchId = '';
      // 更新当前地区层级数据
      dataValue.current.forEach(v => {
        if (levelMap[level] == 4) {
          transformAreaName(name, v.abbr_name, () => {
            branchId = v.city_id || v.town_code;
          });
        } else if (v.code == adcode) {
          branchId = v.city_id || v.town_code;
        }
      });
      updateAreaInfo({
        adcode,
        branchId,
        name,
        branchLevel: levelMap[level],
      });
      if (adcode) {
        updateMapData(branchId, adcode, levelMap[level], parent.adcode);
      }
    },
    [updateMapData, updateAreaInfo, dataValue],
  );

  const onBreadcrumbClick = useCallback(
    data => {
      const { branchLevel } = currentUserLevel.current[currentUserLevel.current.length - 1] || {};
      if (data.branchLevel == branchLevel) return;
      updateAreaInfo(data);
      updateMapData(data.branchId, data.adcode, data.branchLevel);
    },
    [updateAreaInfo, updateMapData, currentUserLevel],
  );

  useEffect(
    () => {
      const { branch = [], branchCode, branchId, branchLevel } = currentUser;
      let name = '';
      if (branchId) {
        if (branch.length > 0) {
          const { name: currentName } = branch[branch.length - 1] || {};
          name = currentName;
        } else {
          name = '全国';
        }
        // 更新初始化的层级信息
        currentUserLevel.current = [
          {
            adcode: branchCode || '0',
            branchId,
            name,
            branchLevel,
          },
        ];
        if (branchLevel == 4) {
          const parentAdCode = branchCode.substring(0, 6);
          updateMapData(branchId, branchCode || '0', branchLevel, parentAdCode);
        } else {
          updateMapData(branchId, branchCode || '0', branchLevel);
        }
        updateAreaInfo({
          adcode: branchCode || '0',
          branchId,
          name,
          branchLevel,
        });
      }
      return () => {
        updateAreaInfo({
          adcode: null,
          branchId: null,
          name: null,
          branchLevel: null,
        });
      };
    },
    [currentUser],
  );

  useEffect(
    () => {
      timer.current = setTimeout(() => {
        if (widthRef.current.clientWidth > 1100) {
          setWidth(1100);
        } else if (widthRef.current) {
          setWidth(widthRef.current.clientWidth);
        }
      }, 1000);
      return () => {
        if (timer.current) {
          clearTimeout(timer.current);
        }
      };
    },
    [isParentFull],
  );

  return (
    <CommonBorder
      title={
        <Row type="flex" style={{ width: '100%' }}>
          <Col>站点热力图</Col>
          <Col style={{ flex: 1 }}>
            <Row style={{ width: '100%' }} type="flex" justify="end" align="middle">
              <Col>
                <ChartBreadcrumb
                  dataSource={currentUserLevel.current}
                  onClick={onBreadcrumbClick}
                />
              </Col>
            </Row>
          </Col>
        </Row>
      }
      loading={loading || mapLoading}
    >
      <div className={styles.mapContainer} ref={widthRef}>
        {mapData ? (
          <MapChart
            width={width || widthRef.current.clientWidth}
            dadaSource={mapData}
            dataValue={dataValue.current}
            onClick={id => onMapClick(id)}
            level={level.current}
            showDot={level.current == 4}
          />
        ) : (
          <NoDate style={{ minHeight: widthRef.current.clientHeight }} />
        )}
      </div>
      <DetailModal
        cm_id={cmId}
        visible={visible}
        token={screenToken}
        onClose={() => setVisible(false)}
      />
    </CommonBorder>
  );
};

export default connect(({ loading, global }) => ({
  screenToken: global.screenToken,
  currentUser: global.screenLoginInfo,
  loading: loading.effects['chartData/getAreaYzData'],
}))(React.memo(Map));
